home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 October
/
EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso
/
Aminet
/
gfx
/
show
/
Easy_MPEG105.lha
/
Easy_MPEG
/
Easy_MPEG.rexx
< prev
next >
Wrap
OS/2 REXX Batch file
|
1995-03-05
|
19KB
|
708 lines
/* ******************* Easy_MPEG Version 1.04 *********************** */
/* ******************* Scott A. Tribbey *********************** */
/* ******************* March 3,1995 *********************** */
/* Painless MPEG! Yup this should make it easy for anybody */
/* to create their own MPEG movies */
/* AREXX script for making MPEG-1 video streams using */
/* the Berkley University MPEG-1 encoder for the Amiga */
/* This macro will create the MPEG-1 stream from 24bit frames */
/* that have been or are being created by a ray tracer or */
/* other graphics output program */
/* The program uses the MPEG-1 encoder to create individual GOPS */
/* or 'Groups Of Pictures' as another application produces the frames */
/* In this way, hard drive space is conserved, as everytime the */
/* number of produced frames available is enough to encode a GOP */
/* the frames will be converted to a GOP and deleted */
/* This allows for very large animations to be constructed on a */
/* system with only modest hard drive space */
/* TRACE('results') */
IF ARG() = 1 THEN
DO
IF EXISTS( 'MPEG.settings' ) THEN
DO
Call ReadParams()
GOPS_COMPLETE = 0 /* Just here to initialize variable */
END
ELSE
Call InitGlobals()
PARSE ARG FrameName StFrame EndFrame Xdim Ydim OutFile FrmDelay DelOldFrms .
IF FrameName == '?' THEN
DO
SAY 'Usage: rx Easy_MPEG Base_Frame_Name Start End Xdim Ydim '
SAY ' OutFileName Delay DelOldFrames'
SAY
SAY 'Example: rx Make_MPEG dh0:IFF/Frame. 0000 0030 352 240 Movie 30 YES'
SAY ' creates Movie.mpg from:'
SAY ' dh0:IFF/Frame.0000 through dh0:IFF/Frame.0030'
SAY ' resolution is 352 by 240, directory scan every 30 sec.'
SAY ' original IFF files will be deleted'
SAY
EXIT /* Quit here */
END
Call GetFileInDir()
Call GetFrameName()
Call CalcGOPS()
END
ELSE
DO
IF EXISTS( 'MPEG.settings' ) THEN
DO
Call ReadParams()
Call GetFileInDir()
Call CalcGOPS()
GOPS_COMPLETE = 0 /* Just here to initialize variable */
Call Stats()
Call RunHost()
END
ELSE
DO
Call InitGlobals()
Call CalcGOPS()
Call Stats()
Call RunHost()
END
END
/* Save Parameters in the MPEG.settings file for future reference in case this session
gets interrupted */
Call SaveParams()
/* This first section is where the program checks to see if any of */
/* the work is already done. If any GOP's have been produced, then */
/* the program starts from where it was last interrupted */
Error = 0
DO I = 0 to TOT_GOPS - 1 UNTIL Error = 1
IF ~ EXISTS(InputDir || OutFile || '.mpg' || '.gop.' || I)
THEN Error = 1
END
GOPS_COMPLETE = I
Call Stats()
Call WriteParamFile()
/* change HOST address to AmigaDOS and set a decent size stack */
ADDRESS ('COMMAND')
'Stack 30000'
/* Wait for and create individual GOPS as frames are available */
/* This will run forever if it never gets all the appropriate frames */
/* Pressing CTRL-C here will break the program */
/* Main loop where frames are scanned for */
DO UNTIL GOPS_COMPLETE == TOT_GOPS
SAY 'Waiting for Frames for GOP 'GOPS_COMPLETE
SAY '***** PRESS CTRL-C TO ABORT *****'
LastGOPFrm = StFrame + (GOPS_COMPLETE * GOP_SIZE) + GOP_SIZE
IF LastGOPFrm > EndFrame THEN
LastGOPFrm = EndFrame
/* Create ZERO padded frame number for file name */
FrmNumber = RIGHT(LastGOPFrm,LENGTH(StFrame),0)
SAY 'Waiting for' FrameName || FrmNumber
SAY ''
IF EXISTS( InputDir || FrameName || FrmNumber ) THEN
DO
/* Check if this is the last frame of the animation */
/* if it is, then we must check it by using the OPEN() */
/* function to see if it is complete */
/* if it isn't then we BREAK out of this DO segment and */
/* wait again */
IF FrmNumber == EndFrame THEN
IF OPEN( TESTF , InputDir || FrameName || FrmNumber ) THEN
DO
BOGUS = CLOSE( TESTF )
IF ((TOT_FRAMES // GOP_SIZE) > 0) & ,
(GOPS_COMPLETE = TOT_GOPS - 1) THEN
DO
GOP_SIZE = TOT_FRAMES // GOP_SIZE
LastGOPFrm = LastGOPFrm + 1
END
ELSE IF ((TOT_FRAMES // GOP_SIZE) == 0) & ,
(GOPS_COMPLETE = TOT_GOPS - 1) THEN
LastGOPFrm = LastGOPFrm + 1
END
ELSE
BREAK
/* First turn IFF-24 frames into .PPM files */
/* and delete the original IFF-24 frames if requested */
DO x = (LastGOPFrm - GOP_SIZE) to (LastGOPFrm - 1)
FrmNumber = RIGHT( x ,LENGTH(StFrame),0)
SAY 'Converting Frame'FrmNumber'to PPM format'
RC = 0
'24toPPM >NIL:' InputDir || FrameName || FrmNumber ,
InputDir || FrameName || FrmNumber || '.ppm'
/* Check to see if 24toppm failed due to wrong number */
/* of bitplanes and use ilbmtoppm instead */
IF RC == 20 THEN
'ILBMtoPPM <'InputDir || FrameName || FrmNumber ,
'>'||InputDir || FrameName || FrmNumber || '.ppm'
IF DelOldFrms == 'YES' THEN
'delete' InputDir || FrameName || FrmNumber
END
'mpeg_encode -gop' GOPS_COMPLETE OutFile||'.param'
GOPS_COMPLETE = GOPS_COMPLETE + 1
/* Now Delete the PPM files */
DO x = (LastGOPFrm - GOP_SIZE) to (LastGOPFrm - 1)
FrmNumber = RIGHT( x ,LENGTH(StFrame),0)
'delete' InputDir || FrameName || FrmNumber || '.ppm'
END
Call Stats()
END
IF GOPS_COMPLETE == TOT_GOPS THEN
BREAK
/* Put in a frame search delay so as not to absorb processor time */
Call delay( FrmDelay * 50 )
/* ADDRESS COMMAND 'wait' FrmDelay THIS USED TOO MUCH CPU TIME */
END
/* Now that all graphic files are done generating */
/* combine all the GOPS into an MPEG file */
/* Here is where we give the final command to mpeg_encode */
/* which then combines the GOP's into a full MPEG-1 file */
'mpeg_encode -combine_gops' OutFile||'.param'
/* Now Delete the GOPS and we're done! */
DO I = 0 to (TOT_GOPS - 1)
'delete' InputDir || OutFile || '.mpg' || '.gop.' || I
END
SAY '------------------------------'
SAY ' Processing Complete!'
SAY '------------------------------'
SAY
/* Here is where the last little OK window pops up */
/* if you don't like that, then just comment the following */
/* line out of the program */
Call Request(300,100,"Processing Complete",,"OK",,)
EXIT
/* ================================================================== */
/* This is where the functions are defined */
/* ================================================================== */
/* This separates the FrameName and InputDir from the input string */
GetFrameName:
IF LASTPOS('/' , FrameName ) > 0 THEN
DO
FileInDir = LEFT( FrameName, LASTPOS('/' , FrameName )-1 )
InputDir = LEFT( FrameName, LASTPOS('/' , FrameName ) )
FrameName = SUBSTR( FrameName, LASTPOS('/' , FrameName )+1 )
END
ELSE
InputDir = ''
RETURN 0
GetFileInDir:
IF LASTPOS('/' , InputDir ) > 0 THEN
FileInDir = LEFT( InputDir, LASTPOS('/' , InputDir )-1 )
ELSE
FileInDir = ''
RETURN 0
/* This initializes the global variables in case there */
/* is no MPEG.settings file to read them from */
InitGlobals:
FrameName = 'Pic.'
StFrame = '0000'
EndFrame = '0030'
Xdim = 160
Ydim = 120
InputDir = 'input/'
FileInDir = 'input'
PATTERN = 'IPBP'
IQScale = 2
PQScale = 4
BQScale = 6
FrmDelay = 60
DelOldFrms = 'YES'
OutFile = 'Movie'
GOPS_COMPLETE = 0
RETURN 0
/* This prints the Status to the CON: window */
Stats:
SAY '' /* This is a clear screen character */
SAY 'Easy_MPEG Scott Tribbey 1995 All rights reserved'
SAY 'MPEG Stream Status'
SAY '--------------------------------------------------'
SAY 'Start Frame :' FrameName || StFrame
SAY 'End Frame :' FrameName || EndFrame
SAY 'Frame Width :' Xdim
SAY 'Frame Height :' Ydim
SAY 'Input Dir. :' InputDir
SAY 'Encode Patt. :' PATTERN
SAY 'IQScale :' IQScale
SAY 'PQScale :' PQScale
SAY 'BQScale :' BQScale
SAY 'GOP_SIZE :' GOP_SIZE
SAY 'Total Frames :' TOT_FRAMES
SAY 'Dir. Scan :' FrmDelay 'sec.'
SAY 'Del Old Frms :' DelOldFrms
SAY 'Total GOPS :' TOT_GOPS
SAY 'OutFile Name :' OutFile || '.mpg'
SAY '--------------------------------------------------'
SAY 'GOPS Complete:' GOPS_COMPLETE '(' (GOPS_COMPLETE / TOT_GOPS * 100) '% )'
SAY '--------------------------------------------------'
SAY
SAY
RETURN 0
/* Store current MPEG parameters in MPEG.settings file */
SaveParams:
OPEN( SETFILE,'MPEG.settings', 'W' )
WRITELN( SETFILE , FrameName )
WRITELN( SETFILE , InputDir )
WRITELN( SETFILE , StFrame )
WRITELN( SETFILE , EndFrame )
WRITELN( SETFILE , Xdim )
WRITELN( SETFILE , Ydim )
WRITELN( SETFILE , OutFile )
WRITELN( SETFILE , FrmDelay )
WRITELN( SETFILE , DelOldFrms )
WRITELN( SETFILE , IQScale )
WRITELN( SETFILE , PQScale )
WRITELN( SETFILE , BQScale )
WRITELN( SETFILE , PATTERN )
CLOSE( SETFILE )
RETURN 0
/* Read MPEG parameters from MPEG.settings file */
ReadParams:
OPEN( SETFILE,'MPEG.settings', 'R' )
FrameName = READLN( SETFILE )
InputDir = READLN( SETFILE )
StFrame = READLN( SETFILE )
EndFrame = READLN( SETFILE )
Xdim = READLN( SETFILE )
Ydim = READLN( SETFILE )
OutFile = READLN( SETFILE )
FrmDelay = READLN( SETFILE )
DelOldFrms = READLN( SETFILE )
IQScale = READLN( SETFILE )
PQScale = READLN( SETFILE )
BQScale = READLN( SETFILE )
PATTERN = READLN( SETFILE )
CLOSE( SETFILE )
RETURN 0
/* Setup some MPEG parameters and calc. the number of GOPS */
/* Calculate a reasonable GOP size ( at least 3 frames ) */
CalcGOPS:
GOP_SIZE = LENGTH(PATTERN)
I = 0
DO I = I + 1 UNTIL GOP_SIZE >= 0
GOP_SIZE = I * LENGTH(PATTERN)
END
IF EndFrame <= StFrame
THEN DO
EndFrame = StFrame + 1
Call Request(300,100,"You need more frames than that!",,"OK",,)
END
TOT_FRAMES = EndFrame - StFrame + 1
TOT_GOPS = TRUNC( TOT_FRAMES / GOP_SIZE )
IF TOT_FRAMES // GOP_SIZE ~= 0 THEN
TOT_GOPS = TOT_GOPS + 1
IF TOT_GOPS == 0
THEN
DO
Call Request(300,100,"You need more frames than that!",,"OK",,)
/* SAY
SAY ' Hey you''ll need more frames than that!!!'
SAY
EXIT */
END
RETURN 0
/* This function creates the .param file which contains the operational */
/* parameters for the mpeg_encode program */
WriteParamFile:
SAY 'Compiling mpeg_encode Parameter File...'
SAY
OPEN( PARMFILE, Outfile || '.param', 'W' )
WRITELN( PARMFILE , '# This parameter file created by Easy_MPEG.rexx' )
WRITELN( PARMFILE , '# An Arexx program by Scott Tribbey 1995' )
WRITELN( PARMFILE , '' )
WRITELN( PARMFILE , '' )
WRITELN( PARMFILE , 'PATTERN ' || PATTERN )
WRITELN( PARMFILE , 'OUTPUT ' || InputDir || OutFile || '.mpg' )
WRITELN( PARMFILE , '' )
WRITELN( PARMFILE , 'BASE_FILE_FORMAT PPM' )
WRITELN( PARMFILE , 'GOP_SIZE ' GOP_SIZE )
WRITELN( PARMFILE , 'SLICES_PER_FRAME 1 ' )
WRITELN( PARMFILE , '' )
WRITELN( PARMFILE , 'PIXEL HALF' )
WRITELN( PARMFILE , 'RANGE 10' )
WRITELN( PARMFILE , 'PSEARCH_ALG LOGARITHMIC' )
WRITELN( PARMFILE , 'BSEARCH_ALG CROSS2' )
WRITELN( PARMFILE , 'IQSCALE 'IQScale )
WRITELN( PARMFILE , 'PQSCALE 'PQScale )
WRITELN( PARMFILE , 'BQSCALE 'BQScale )
WRITELN( PARMFILE , '' )
WRITELN( PARMFILE , 'REFERENCE_FRAME ORIGINAL' )
WRITELN( PARMFILE , 'FORCE_ENCODE_LAST_FRAME' )
WRITELN( PARMFILE , '' )
WRITELN( PARMFILE , 'YUV_SIZE '||Xdim||'x'||Ydim )
WRITELN( PARMFILE , 'INPUT_DIR '||FileInDir )
WRITELN( PARMFILE , 'INPUT' )
WRITELN( PARMFILE , FrameName || '*' || '.ppm ' '[' || ,
StFrame || '-' || EndFrame || ']')
WRITELN( PARMFILE , 'END_INPUT' )
WRITELN( PARMFILE , 'INPUT_CONVERT *' )
CLOSE( PARMFILE )
RETURN 0
RunHost:
if ~show('l', "rexxarplib.library") then do
check = addlib('rexxarplib.library',0,-30,0)
end
if ~show('l', "rexxsupportlib.library") then do
check = addlib('rexxsupport.library',0,-30,0)
end
ADDRESS COMMAND
/* The following command is the only way to use the createhost() */
/* function without locking up the script */
Call OPENPORT(MPEGPORT)
'Run ' 'SYS:Rexxc/rx ''Call createhost(MPEGHOST, MPEGPORT,)'''
Call delay(100) /* delay to allow the host to get set up */
idcmp = 'CLOSEWINDOW+GADGETDOWN+GADGETUP'
flags = 'WINDOWCLOSE+WINDOWDRAG+WINDOWDEPTH'
call OpenWindow(MPEGHOST, 50, 50, 340, 200, idcmp, flags, "Easy_MPEG 1.04 Scott Tribbey 1995")
call SetAPen(MPEGHOST,1)
/* Now Add the gadgets */
call AddGadget(MPEGHOST,120 ,15 ,00 ,FrameName ,"%l STRING %d %g",200 )
call AddGadget(MPEGHOST,120 ,30 ,01 ,InputDir ,"%l STRING %d %g",200 )
call AddGadget(MPEGHOST,120 ,45 ,02 ,StFrame ,"%l STRING %d %g",100 )
call AddGadget(MPEGHOST,120 ,60 ,03 ,EndFrame ,"%l STRING %d %g",100 )
call AddGadget(MPEGHOST,135 ,75 ,04 ,Xdim ,"%l STRING %d %g",40 )
call AddGadget(MPEGHOST,205 ,75 ,05 ,Ydim ,"%l STRING %d %g",40 )
call AddGadget(MPEGHOST,120 ,120 ,06 ,OutFile ,"%l STRING %d %g",200 )
call AddGadget(MPEGHOST,120 ,135 ,07 ,FrmDelay ,"%l STRING %d %g",40 )
call AddGadget(MPEGHOST,120 ,150 ,08,"Del. Old Frames" ,"%l STRING %d")
call AddGadget(MPEGHOST,252 ,170 ,09,"Start\Scanning" ,"%l STRING %d")
call AddGadget(MPEGHOST,120 ,170 ,10,"Quit\Program" ,"QUIT")
call AddGadget(MPEGHOST,244 ,45 ,11,"File\Requester" ,"%l STRING %d")
call AddGadget(MPEGHOST,135 ,90 ,12,IQScale ,"%l STRING %d %g",40 )
call AddGadget(MPEGHOST,205 ,90 ,13,PQScale ,"%l STRING %d %g",40 )
call AddGadget(MPEGHOST,275 ,90 ,14,BQScale ,"%l STRING %d %g",40 )
call AddGadget(MPEGHOST,120 ,105 ,15,PATTERN ,"%l STRING %d %g",200 )
/* Now Add the gadget labels */
call Move(MPEGHOST,10,22)
call Text(MPEGHOST," Frame Name:")
call Move(MPEGHOST,10,37)
call Text(MPEGHOST," Input Dir:")
call Move(MPEGHOST,10,52)
call Text(MPEGHOST," Start Frame:")
call Move(MPEGHOST,10,67)
call Text(MPEGHOST," End Frame:")
call Move(MPEGHOST,10,82)
call Text(MPEGHOST," Resolution: X")
call Move(MPEGHOST,190,82)
call Text(MPEGHOST,"Y")
call Move(MPEGHOST,10,97)
call Text(MPEGHOST,"Quant. Scale: I")
call Move(MPEGHOST,190,97)
call Text(MPEGHOST,"P")
call Move(MPEGHOST,260,97)
call Text(MPEGHOST,"B")
call Move(MPEGHOST,10,112)
call Text(MPEGHOST,"Frm. Pattern:")
call Move(MPEGHOST,10,127)
call Text(MPEGHOST," Out File:")
call Move(MPEGHOST,10,142)
call Text(MPEGHOST," Dir. Scan:")
call Move(MPEGHOST,170,142)
call Text(MPEGHOST,"Sec.")
CALL MessageLoop()
call Exit(MPEGHOST)
Call CLOSEPORT(MPEGPORT)
IF QUIT = 1 THEN EXIT(0)
RETURN 0
MessageLoop:
/* MAIN message loop */
keep_going=1
DO WHILE keep_going=1
/* Wait for at least one message to arrive */
t=WAITPKT(MPEGPORT)
/* process *ALL* the messages waiting at this port */
DO ff=1
p=GETPKT(MPEGPORT)
/* p=NULL means not more messages at this port.
This is the *ONLY* time you should leave this loop! */
IF p='0000 0000'x THEN LEAVE ff /* message port empty */
/* get the message from the the port packet */
command=GETARG(p)
/* REPLY() as soon as you can, as soon as you are through extracting
data from the packet with GETARG() */
t=REPLY(p,0)
/* Ignore any messages received after the CLOSEWINDOW */
IF keep_going=0 THEN ITERATE ff
/* now we can see what the message contains, and act on it */
PARSE VAR command arg1' 'arg2' 'arg3' 'arg4' '
SELECT
WHEN arg1='CLOSEWINDOW' | arg1 = 'QUIT' THEN
DO
keep_going=0
QUIT = 1
END
WHEN arg1='GADGETUP' THEN
DO
SELECT
WHEN arg2='STRING' THEN
DO
SELECT
WHEN arg3 = 0 THEN FrameName = arg4
WHEN arg3 = 1 THEN
DO
InputDir = arg4
Call GetFileInDir()
END
WHEN arg3 = 2 THEN StFrame = arg4
WHEN arg3 = 3 THEN EndFrame = arg4
WHEN arg3 = 4 THEN Xdim = arg4
WHEN arg3 = 5 THEN Ydim = arg4
WHEN arg3 = 6 THEN OutFile = arg4
WHEN arg3 = 7 THEN FrmDelay = arg4
WHEN arg3 = 8 THEN
IF DelOldFrms = 'YES' THEN
DelOldFrms = 'NO'
ELSE
DelOldFrms = 'YES'
WHEN arg3 = 9 THEN keep_going=0
WHEN arg3 = 10 THEN FrmDelay = arg4
WHEN arg3 = 11 THEN Call GetBaseFile()
WHEN arg3 = 12 THEN IQScale = arg4
WHEN arg3 = 13 THEN PQScale = arg4
WHEN arg3 = 14 THEN BQScale = arg4
WHEN arg3 = 15 THEN PATTERN = arg4
OTHERWISE
END
Call CalcGOPS()
Call Stats()
END
OTHERWISE
END
END
OTHERWISE DO
SAY 'arg1 'arg1
SAY 'arg2 'arg2
SAY 'arg3 'arg3
END
END
END
END
RETURN 0
/* This is where we use the ARP file requester to get the Base Filename */
GetBaseFile:
FileName = GetFile(100,100,FileInDir,,,)
IF FileName ~= '' THEN
DO
FrameName = FileName
Call GetFrameName()
call RemoveGadget(MPEGHOST,00)
call RemoveGadget(MPEGHOST,01)
call AddGadget(MPEGHOST,120 ,15 ,00 ,FrameName ,"%l STRING %d %g",200 )
call AddGadget(MPEGHOST,120 ,30 ,01 ,InputDir ,"%l STRING %d %g",200 )
END
RETURN 0